package com.xckj.cycling.framework

import android.content.ComponentName
import android.content.Context
import android.content.DialogInterface
import android.content.Intent
import android.os.Bundle
import android.os.IBinder
import android.text.TextUtils
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import androidx.appcompat.app.AlertDialog
import androidx.appcompat.app.AppCompatActivity
import androidx.health.connect.client.HealthConnectClient
import androidx.health.connect.client.PermissionController
import androidx.health.connect.client.permission.HealthPermission
import androidx.health.connect.client.records.HeartRateRecord
import androidx.health.connect.client.records.SleepSessionRecord
import androidx.health.connect.client.records.SleepStageRecord
import androidx.lifecycle.lifecycleScope
import com.gyf.immersionbar.ImmersionBar
import com.xckj.cycling.R
import com.xckj.cycling.activity.HealthDelegateActivity
import com.xckj.cycling.context.AppContext
import com.xckj.cycling.utils.AppManager
import com.xckj.cycling.utils.LanguageUtils
import com.xckj.cycling.utils.PackageUtils
import com.xckj.cycling.utils.ToastUtils
import com.xckj.cycling.view.dialog.LoadingDialog
import com.xckj.cycling.viewmodel.BleViewModel
import com.xckj.cycling.viewmodel.HealthViewModel
import com.xckj.cycling.viewmodel.LoginViewModel
import com.xckj.cycling.viewmodel.MapViewModel
import kotlinx.coroutines.launch

/**
 * @Author: liyang
 * @Describe: kt Activity的基类
 * @Date: 2023/2/25 22:02
 */
abstract class BaseActivityKt : AppCompatActivity(), IBaseView {

    protected val bleViewModel: BleViewModel by lazyGlobalViewModel()

    companion object {
        const val PACKAGE = "com.google.android.apps.healthdata"
    }

    private val healthViewModel: HealthViewModel by lazyGlobalViewModel()

    protected suspend fun checkPermissionsAndRun(healthConnectClient: HealthConnectClient) {
        // For alpha09 and earlier versions, use getGrantedPermissions(PERMISSIONS) instead
        val granted = healthConnectClient.permissionController.getGrantedPermissions()
        if (granted.containsAll(PERMISSIONS)) {
            loadHealth()
        } else {
            requestPermissions.launch(PERMISSIONS)
        }
    }

    // Create the permissions launcher.
    protected val requestPermissionActivityContract =
        PermissionController.createRequestPermissionResultContract()
    protected val PERMISSIONS =
        setOf(
//            HealthPermission.getReadPermission(StepsRecord::class),
            HealthPermission.getReadPermission(SleepStageRecord::class),
            HealthPermission.getReadPermission(SleepSessionRecord::class),
//            HealthPermission.getReadPermission(HeartRateVariabilityRmssdRecord::class),
            HealthPermission.getReadPermission(HeartRateRecord::class)
        )
    protected val requestPermissions =
        registerForActivityResult(requestPermissionActivityContract) { granted ->
            if (granted.containsAll(PERMISSIONS)) {
                loadHealth()
                // Permissions successfully granted
            } else {
                startActivity(packageManager.getLaunchIntentForPackage(PACKAGE))
                // Lack of required permissions
            }
        }

    protected val client by lazy { HealthConnectClient.getOrCreate(AppContext.globalContext()) }
    protected open fun isNotEmpty(textView: TextView): Boolean {
        return !TextUtils.isEmpty(textView.text)
    }

    protected val viewModel: MapViewModel by lazyGlobalViewModel()
    protected val loginViewModel: LoginViewModel by lazyGlobalViewModel()

    private var loadingDialog: LoadingDialog? = null
    private var dialogCount = 0
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        AppManager.getInstance().addActivity(this)
        MvvmUtils.findViewBinding(this, window?.decorView as? ViewGroup, LayoutInflater.from(this))
            ?.apply {
                setContentView(this.root)

//                val params = FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, QMUIStatusBarHelper.getStatusbarHeight(baseContext))
//                findViewById<View>(R.id.common_top_bar_view)?.layoutParams = FrameLayout.LayoutParams(params)

                initView(this.root, savedInstanceState)
                findViewById<View?>(R.id.btn_back)?.setOnClickListener {
                    finish()
                }
            }
        window?.decorView?.systemUiVisibility =
            View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN or View.SYSTEM_UI_FLAG_LAYOUT_STABLE or View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR
    }

    override fun attachBaseContext(newBase: Context) {
        super.attachBaseContext(LanguageUtils.newContext(newBase))
    }

    protected open fun initView(root: View, savedInstanceState: Bundle?) {
    }

    protected fun notifyViewBinding() {
        setTitle()
        initData()
        setListener()
        initStatusBar()
    }


    protected open fun setTitle() {}

    /**
     * 初始化数据
     */
    protected open fun initData() {

    }

    /**
     * 设置监听
     */
    protected open fun setListener() {

    }

    /**
     * 初始化沉浸式状态栏
     */
    private fun initStatusBar() {
    }

    /**
     * 是否使用沉浸式状态栏
     *
     * @return true or false
     */
    protected open fun isStatusBarEnabled(): Boolean {
        return true
    }

    /**
     * 状态栏字体是否深色模式
     *
     * @return true or false
     */
    protected open fun isStatusBarDarkFont(): Boolean {
        return true
    }

    /**
     * 初始化沉浸式状态栏
     *
     * @return ImmersionBar
     */
    protected open fun createStatusBarConfig(): ImmersionBar {
        return ImmersionBar.with(this) /*默认状态栏字体颜色为黑色*/
            .statusBarDarkFont(isStatusBarDarkFont()).keyboardEnable(false) /*指定导航栏背景颜色*/
            .navigationBarColor(R.color.white) /*状态栏字体和导航栏内容自动变色，必须指定状态栏颜色和导航栏颜色才可以自动变色*/
            .autoDarkModeEnable(true).autoNavigationBarDarkModeEnable(true)
    }


    override fun showMessage(message: CharSequence?) {
        if (!TextUtils.isEmpty(message)) {
            runOnUiThread {
                ToastUtils.showToast(message)
            }
        }
    }

    override fun showLoading() {
        runOnUiThread {
            dialogCount++
            if (null == loadingDialog || !loadingDialog!!.isShowing()) {
                loadingDialog = LoadingDialog(this).apply {
                    create()
                }
            }
            if (loadingDialog?.isShowing() != true) {
                loadingDialog?.show()
            }
        }
    }

    override fun hideDialog() {
        runOnUiThread {
            dialogCount--
            Log.e("hideDialog", "loading Count$dialogCount")
            if (null == loadingDialog) {
                return@runOnUiThread
            }
            if (dialogCount <= 0) {
                loadingDialog!!.dismiss()
            }
        }
    }

    protected fun loadHealth() {
        showLoading()
        healthViewModel.loadData(client) {
            showMessage(getString(R.string.data_success))
            hideDialog()
            if (this is HealthDelegateActivity) {
                finish()
            }
        }
    }

    private fun checkFinish() {
        if (this@BaseActivityKt is HealthDelegateActivity) {
            finish()
        }
    }

    protected fun checkHealth() {
        when (HealthConnectClient.sdkStatus(this)) {
            HealthConnectClient.SDK_AVAILABLE -> {
                val connect = check()
                if (!connect) {
                    showMessage("Health Service connect failed")
                    checkFinish()
                    return
                }
                lifecycleScope.launch {
                    checkPermissionsAndRun(client)
                }
            }
            HealthConnectClient.SDK_UNAVAILABLE, HealthConnectClient.SDK_UNAVAILABLE_PROVIDER_UPDATE_REQUIRED -> {
                AlertDialog.Builder(this).setTitle(getString(R.string.dialog_tips)).setMessage(
                    getString(
                        R.string.pleae_install_or_update
                    )
                ).setNegativeButton(R.string.cancel, object : DialogInterface.OnClickListener {
                    override fun onClick(dialog: DialogInterface?, which: Int) {
                        checkFinish()
                    }

                }).setPositiveButton(getString(R.string.install_or_update),
                    object : DialogInterface.OnClickListener {
                        override fun onClick(dialog: DialogInterface?, which: Int) {
                            PackageUtils.goMarket(
                                this@BaseActivityKt,
                                PACKAGE
                            )
                            checkFinish()

                        }

                    }).setCancelable(false).show()
            }

        }

    }

    override fun onDestroy() {
        super.onDestroy()
        AppManager.getInstance().killActivity(this)
    }


    private fun check(): Boolean {
        var connect = false
        try {
            connect = bindService(
                Intent()
                    .setPackage("com.google.android.apps.healthdata")
                    .setAction("androidx.health.ACTION_BIND_HEALTH_DATA_SERVICE"),
                object : android.content.ServiceConnection {
                    override fun onServiceConnected(name: ComponentName?, service: IBinder?) {
                    }

                    override fun onServiceDisconnected(name: ComponentName?) {
                    }

                },
                BIND_AUTO_CREATE or BIND_ADJUST_WITH_ACTIVITY
            )
        } catch (exception: SecurityException) {
            connect = false
        }
        return connect
    }
}